bitkeeper revision 1.746.1.1 (403c8c65qu1dJWHVajQ4wyGMSQjo1Q)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 25 Feb 2004 11:52:05 +0000 (11:52 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 25 Feb 2004 11:52:05 +0000 (11:52 +0000)
Many files:
  Clean up task list in Xen. Fix a bug in xentrace for some glibc versions.

tools/xentrace/xentrace.c
xen/arch/i386/pdb-stub.c
xen/common/dom0_ops.c
xen/common/domain.c
xen/common/keyhandler.c
xen/common/schedule.c
xen/drivers/block/xen_block.c
xen/drivers/block/xen_vbd.c
xen/include/xeno/sched.h

index 526c8152fc8b99c629c88c1e61353bc6cd9498bc..ab170050c7ce425278159642ec1fd6f8f630f46d 100644 (file)
@@ -407,8 +407,7 @@ int main(int argc, char **argv)
 {
     int ret;
     FILE *logfile = stdout;
-
-    const struct sigaction act = { .sa_handler = close_handler };
+    struct sigaction act;
 
     opts.outfile = 0;
     opts.num_cpus = 1;
@@ -421,6 +420,7 @@ int main(int argc, char **argv)
         logfile = fopen(opts.outfile, "w");
     
     /* ensure that if we get a signal, we'll do cleanup, then exit */
+    act.sa_handler = close_handler;
     sigaction(SIGHUP,  &act, 0);
     sigaction(SIGTERM, &act, 0);
     sigaction(SIGINT,  &act, 0);
index 87fb907fb8fe94f3d79680691ab7b6154b72aa82..e92e5cf30a1e67b8c2c9201732554ec70f763c1a 100644 (file)
@@ -86,14 +86,14 @@ pdb_process_query (char *ptr)
     }
     else if (strcmp(ptr, "fThreadInfo") == 0)
     {
-        struct task_struct *p = &idle0_task;
+        struct task_struct *p;
         u_long flags;
        int count = 0, buf_idx = 0;
 
         read_lock_irqsave (&tasklist_lock, flags);
 
        pdb_out_buffer[buf_idx++] = 'm';
-        while ( (p = p->next_task) != &idle0_task )
+        for_each_domain ( p )
        {
            domid_t domain = p->domain + PDB_DOMAIN_OFFSET;
 
index c225dffd3f2f1ce6d466e7eb4b65e26bdbc86b4e..ddae55d370c2c7280abcf170ab93aae9e9b95d1c 100644 (file)
@@ -152,7 +152,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     {
         domid_t dom = op->u.destroydomain.domain;
         int force = op->u.destroydomain.force;
-        ret = (dom == IDLE_DOMAIN_ID) ? -EPERM : kill_other_domain(dom, force);
+        ret = kill_other_domain(dom, force);
     }
     break;
 
@@ -210,9 +210,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         unsigned long  warpl   = op->u.adjustdom.warpl;
         unsigned long  warpu   = op->u.adjustdom.warpu;
 
-        ret = -EPERM;
-        if ( dom != IDLE_DOMAIN_ID )
-            ret = sched_adjdom(dom, mcu_adv, warp, warpl, warpu);
+        ret = sched_adjdom(dom, mcu_adv, warp, warpl, warpu);
     }
     break;
 
@@ -256,18 +254,19 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
     case DOM0_GETDOMAININFO:
     { 
-        struct task_struct *p = &idle0_task;
+        struct task_struct *p;
         u_long flags;
         int i;
 
         read_lock_irqsave (&tasklist_lock, flags);
 
-        while ( (p = p->next_task) != &idle0_task )
-            if ( !is_idle_task(p) && 
-                 (p->domain >= op->u.getdomaininfo.domain) )
+        for_each_domain ( p )
+        {
+            if ( p->domain >= op->u.getdomaininfo.domain )
                 break;
+        }
 
-        if ( p == &idle0_task )
+        if ( p == NULL )
         {
             ret = -ESRCH;
         }
index 3aef0fe69e84bddc4d2e11eabad90c82bd41bbf0..85a3c8ae31a806261006185ab780be434f5fe6e1 100644 (file)
 /* Both these structures are protected by the tasklist_lock. */
 rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;
 struct task_struct *task_hash[TASK_HASH_SIZE];
+struct task_struct *task_list;
 
 struct task_struct *do_createdomain(domid_t dom_id, unsigned int cpu)
 {
-    int retval;
     char buf[100];
-    struct task_struct *p = NULL;
+    struct task_struct *p, **pp;
     unsigned long flags;
 
-    retval = -ENOMEM;
-    p = alloc_task_struct();
-    if ( p == NULL ) return NULL;
+    if ( (p = alloc_task_struct()) == NULL )
+        return NULL;
     memset(p, 0, sizeof(*p));
 
     atomic_set(&p->refcnt, 1);
@@ -48,37 +47,51 @@ struct task_struct *do_createdomain(domid_t dom_id, unsigned int cpu)
     p->domain    = dom_id;
     p->processor = cpu;
 
-    /* We use a large intermediate to avoid overflow in sprintf. */
-    sprintf(buf, "Domain-%llu", dom_id);
-    strncpy(p->name, buf, MAX_DOMAIN_NAME);
-    p->name[MAX_DOMAIN_NAME-1] = '\0';
-
-    spin_lock_init(&p->blk_ring_lock);
-    spin_lock_init(&p->event_channel_lock);
-
-    p->shared_info = (void *)get_free_page(GFP_KERNEL);
-    memset(p->shared_info, 0, PAGE_SIZE);
-    SHARE_PFN_WITH_DOMAIN(virt_to_page(p->shared_info), p);
+    memcpy(&p->thread, &idle0_task.thread, sizeof(p->thread));
 
-    p->mm.perdomain_pt = (l1_pgentry_t *)get_free_page(GFP_KERNEL);
-    memset(p->mm.perdomain_pt, 0, PAGE_SIZE);
+    if ( p->domain != IDLE_DOMAIN_ID )
+    {
+        /* We use a large intermediate to avoid overflow in sprintf. */
+        sprintf(buf, "Domain-%llu", dom_id);
+        strncpy(p->name, buf, MAX_DOMAIN_NAME);
+        p->name[MAX_DOMAIN_NAME-1] = '\0';
 
-    init_blkdev_info(p);
+        spin_lock_init(&p->blk_ring_lock);
+        spin_lock_init(&p->event_channel_lock);
+        
+        p->addr_limit = USER_DS;
+        
+        spin_lock_init(&p->page_list_lock);
+        INIT_LIST_HEAD(&p->page_list);
+        p->max_pages = p->tot_pages = 0;
 
-    p->addr_limit = USER_DS;
+        p->shared_info = (void *)get_free_page(GFP_KERNEL);
+        memset(p->shared_info, 0, PAGE_SIZE);
+        SHARE_PFN_WITH_DOMAIN(virt_to_page(p->shared_info), p);
+        
+        p->mm.perdomain_pt = (l1_pgentry_t *)get_free_page(GFP_KERNEL);
+        memset(p->mm.perdomain_pt, 0, PAGE_SIZE);
+        
+        init_blkdev_info(p);
+        
+        write_lock_irqsave(&tasklist_lock, flags);
+        pp = &task_list; /* NB. task_list is maintained in order of dom_id. */
+        for ( pp = &task_list; *pp != NULL; pp = &(*pp)->next_list )
+            if ( (*pp)->domain > p->domain )
+                break;
+        p->next_list = *pp;
+        *pp = p;
+        p->next_hash = task_hash[TASK_HASH(dom_id)];
+        task_hash[TASK_HASH(dom_id)] = p;
+        write_unlock_irqrestore(&tasklist_lock, flags);
+    }
+    else
+    {
+        sprintf(p->name, "Idle-%d", cpu);
+    }
 
     sched_add_domain(p);
 
-    spin_lock_init(&p->page_list_lock);
-    INIT_LIST_HEAD(&p->page_list);
-    p->max_pages = p->tot_pages = 0;
-
-    write_lock_irqsave(&tasklist_lock, flags);
-    SET_LINKS(p);
-    p->next_hash = task_hash[TASK_HASH(dom_id)];
-    task_hash[TASK_HASH(dom_id)] = p;
-    write_unlock_irqrestore(&tasklist_lock, flags);
-
     return p;
 }
 
@@ -141,9 +154,13 @@ void __kill_domain(struct task_struct *p)
      * holds a reference to the domain being queried. Take care!
      */
     write_lock_irqsave(&tasklist_lock, flags);
-    REMOVE_LINKS(p);
-    pp = &task_hash[TASK_HASH(p->domain)];
-    while ( *pp != p ) *pp = (*pp)->next_hash;
+    pp = &task_list;                       /* Delete from task_list. */
+    while ( *pp != p ) 
+        *pp = (*pp)->next_list;
+    *pp = p->next_list;
+    pp = &task_hash[TASK_HASH(p->domain)]; /* Delete from task_hash. */
+    while ( *pp != p ) 
+        *pp = (*pp)->next_hash;
     *pp = p->next_hash;
     write_unlock_irqrestore(&tasklist_lock, flags);
 
index 06e25317739b74f2d64a6060470bcebb2f264933..a71aec760edee0729769f1c513981f4e59a4c1ef 100644 (file)
@@ -108,21 +108,18 @@ void do_task_queues(u_char key, void *dev_id, struct pt_regs *regs)
 
     read_lock_irqsave(&tasklist_lock, flags); 
 
-    p = &idle0_task;
-    do {
+    for_each_domain ( p )
+    {
         printk("Xen: DOM %llu, CPU %d [has=%c], state = %s, "
                "hyp_events = %08x\n", 
                p->domain, p->processor, p->has_cpu ? 'T':'F', 
                task_states[p->state], p->hyp_events); 
         s = p->shared_info; 
-        if( !is_idle_task(p) )
-        {
-            printk("Guest: events = %08lx, events_mask = %08lx\n", 
-                   s->events, s->events_mask); 
-            printk("Notifying guest...\n"); 
-            cpu_mask |= mark_guest_event(p, _EVENT_DEBUG);
-        }
-    } while ( (p = p->next_task) != &idle0_task );
+        printk("Guest: events = %08lx, events_mask = %08lx\n", 
+               s->events, s->events_mask); 
+        printk("Notifying guest...\n"); 
+        cpu_mask |= mark_guest_event(p, _EVENT_DEBUG);
+    }
 
     read_unlock_irqrestore(&tasklist_lock, flags); 
 
index e6450cc54c0cf942bf3fa8d057761aabd11b44de..c2bcb91c0692ebd07237c61f619045a954233433 100644 (file)
@@ -479,15 +479,14 @@ asmlinkage void __enter_scheduler(void)
     {
         u_long t_flags; 
         write_lock_irqsave(&tasklist_lock, t_flags); 
-        p = &idle0_task;
-        do {
-            if ( (p->processor == cpu) && !is_idle_task(p) )
+        for_each_domain ( p )
+        {
+            if ( p->processor == cpu )
             {
                 p->evt -= 0xe0000000;
                 p->avt -= 0xe0000000;
             }
         } 
-        while ( (p = p->next_task) != &idle0_task );
         write_unlock_irqrestore(&tasklist_lock, t_flags); 
         schedule_data[cpu].svt -= 0xe0000000;
     }
index eaf901a328d155c3327c5db5f2403125547fc1e3..4cc24993296bc3a8890c65616cb3705904af7830 100644 (file)
@@ -569,22 +569,16 @@ static void dump_blockq(u_char key, void *dev_id, struct pt_regs *regs)
            NR_PENDING_REQS, pending_prod, pending_cons);
 
     read_lock_irqsave(&tasklist_lock, flags);
-    p = &idle0_task;
-    do {
-        if ( !is_idle_task(p) )
-        {
-            printk("Domain: %llu\n", p->domain);
-            blk_ring = p->blk_ring_base;
-            
-            printk("  req_prod:0x%08x, req_cons:0x%08x resp_prod:0x%08x/"
-                   "0x%08x on_list=%d\n",
-                   blk_ring->req_prod, p->blk_req_cons,
-                   blk_ring->resp_prod, p->blk_resp_prod,
-                   __on_blkdev_list(p));
-        }
-        p = p->next_task;
-    } 
-    while ( (p = p->next_task) != &idle0_task );
+    for_each_domain ( p )
+    {
+        printk("Domain: %llu\n", p->domain);
+        blk_ring = p->blk_ring_base;
+        printk("  req_prod:0x%08x, req_cons:0x%08x resp_prod:0x%08x/"
+               "0x%08x on_list=%d\n",
+               blk_ring->req_prod, p->blk_req_cons,
+               blk_ring->resp_prod, p->blk_resp_prod,
+               __on_blkdev_list(p));
+    }
     read_unlock_irqrestore(&tasklist_lock, flags);
 
     for ( i = 0; i < MAX_PENDING_REQS; i++ )
index 3e25440e52db56f7dea6f7d6e9fada8d35ceb2e8..c2570064d8da503d24c6908424f246587d65fd20 100644 (file)
@@ -557,16 +557,12 @@ long vbd_probe(vbd_probe_t *probe)
     if ( probe->domain == VBD_PROBE_ALL )
     { 
         read_lock_irqsave(&tasklist_lock, flags);
-        p = &idle0_task; 
-        while ( (p = p->next_task) != &idle0_task )
+        for_each_domain ( p )
         {
-            if ( !is_idle_task(p) )
+            if ( (ret = vbd_probe_devices(&probe->xdi, p)) != 0 )
             { 
-                if( (ret = vbd_probe_devices(&probe->xdi, p)) != 0 )
-                { 
-                    read_unlock_irqrestore(&tasklist_lock, flags);
-                    goto out; 
-                }
+                read_unlock_irqrestore(&tasklist_lock, flags);
+                goto out; 
             }
         }
         read_unlock_irqrestore(&tasklist_lock, flags);
index e77d4a5ebc91df8d06acc6514ce9248a182a8fd2..4375d9a7be28283d111c6117bb9ea636e361e1b1 100644 (file)
@@ -140,8 +140,8 @@ struct task_struct
     char name[MAX_DOMAIN_NAME];
 
     struct thread_struct thread;
-    struct task_struct *prev_task, *next_task, *next_hash;
-    
+    struct task_struct *next_list, *next_hash;
+
     /* Event channel information. */
     event_channel_t *event_channel;
     unsigned int     max_event_channel;
@@ -182,8 +182,6 @@ struct task_struct
     mm:          IDLE0_MM,       \
     addr_limit:  KERNEL_DS,      \
     thread:      INIT_THREAD,    \
-    prev_task:   &(_t),          \
-    next_task:   &(_t),          \
     flags:       1<<PF_IDLETASK  \
 }
 
@@ -284,22 +282,14 @@ void continue_cpu_idle_loop(void);
 
 void continue_nonidle_task(void);
 
-/* This hash table is protected by the tasklist_lock. */
+/* This task_hash and task_list are protected by the tasklist_lock. */
 #define TASK_HASH_SIZE 256
 #define TASK_HASH(_id) ((int)(_id)&(TASK_HASH_SIZE-1))
 extern struct task_struct *task_hash[TASK_HASH_SIZE];
+extern struct task_struct *task_list;
 
-#define REMOVE_LINKS(p) do { \
-        (p)->next_task->prev_task = (p)->prev_task; \
-        (p)->prev_task->next_task = (p)->next_task; \
-        } while (0)
-
-#define SET_LINKS(p) do { \
-        (p)->next_task = &idle0_task; \
-        (p)->prev_task = idle0_task.prev_task; \
-        idle0_task.prev_task->next_task = (p); \
-        idle0_task.prev_task = (p); \
-        } while (0)
+#define for_each_domain(_p) \
+ for ( (_p) = task_list; (_p) != NULL; (_p) = (_p)->next_list )
 
 extern void update_process_times(int user);